﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;

namespace GestorSQL.DAO.FileManager
{
    public class AbstractFileManager : IFileManager
    {
        #region IFileManager Members

        public void SaveFile(string path, string fileNameWithOutExtesion, string information, bool overwrite)
        {
            FileInfo file = new FileInfo(Path.Combine(path, string.Format("{0}.{1}", fileNameWithOutExtesion, GetExtension())));
            if (!file.Directory.Exists)
                Directory.CreateDirectory(file.Directory.FullName);
            if (file.Exists && !overwrite)
            {
                file.CopyTo(Path.Combine(path, string.Format("{0}({1}).{2}", fileNameWithOutExtesion, DateTime.Now.Ticks.ToString(), GetExtension())));
                //throw new Exception("El archivo ya existe y no debe ser sobreescrito.");
            }
            ConcreteSaveFile(file, information);
        }

        public string GetFileData(string path, string fileNameWithOutExtesion)
        {
            FileInfo file = new FileInfo(Path.Combine(path, string.Format("{0}.{1}", fileNameWithOutExtesion, GetExtension())));
            if (!file.Exists)
            {
                return string.Empty;
                //throw new Exception("El archivo no existe.");
            }
            return ConcreteOpenFile(file);
        }

        public void CompressFile(string path, string fileNameWithOutExtesion, string compressFileName)
        {
            FileInfo fileInfo = new FileInfo(Path.Combine(path, string.Format("{0}.{1}", fileNameWithOutExtesion, "txt")));

            if (fileInfo.Exists)
            {
                StreamWriter sw;
                string input;

                StreamReader fileStream = new StreamReader(fileInfo.FullName);


                GZipStream gzOut = new GZipStream(File.Create(string.Format("{0}\\{1}.{2}", fileInfo.DirectoryName, compressFileName, GetExtension())), CompressionMode.Compress);
                sw = new StreamWriter(gzOut);
                while ((input = fileStream.ReadLine()) != null)
                    sw.WriteLine(input);

                sw.Close();
                gzOut.Close();
                fileStream.Close();

                fileInfo.Delete();
            }
        }

        public void SaveAppendFile(string path, string fileNameWithOutExtesion, string information)
        {

            FileInfo file = new FileInfo(Path.Combine(path, string.Format("{0}.{1}", fileNameWithOutExtesion, GetExtension())));
            if (!file.Directory.Exists)
                Directory.CreateDirectory(file.Directory.FullName);

            ConcreteSaveAppendFile(file, information);
        }

        public StreamReader GetStreamReader(string path, string fileNameWithOutExtesion)
        {
            FileInfo file = new FileInfo(Path.Combine(path, string.Format("{0}.{1}", fileNameWithOutExtesion, GetExtension())));
            if (!file.Exists)
                throw new FileNotFoundException("El Archivo que se desea leer no existe");

            return ConcreteGetStreamReader(file); 
        }

        public StreamWriter GetStreamWriter(string path, string fileNameWithOutExtesion, bool overwrite)
        {
            FileInfo file = new FileInfo(Path.Combine(path, string.Format("{0}.{1}", fileNameWithOutExtesion, GetExtension())));
            if (!file.Directory.Exists)
                Directory.CreateDirectory(file.Directory.FullName);
            return ConcreteGetStreamWriter(file, overwrite);
        }

        #endregion

        #region Virtual methods
        protected virtual void ConcreteSaveFile(FileInfo file, string information)
        {
            throw new NotImplementedException();
        }

        protected virtual void ConcreteSaveAppendFile(FileInfo file, string information)
        {
            throw new NotImplementedException();
        }

        protected virtual void ConcreteCompressFile(FileInfo fileInfo, string fileNameWithOutExtesion)
        {
            throw new NotImplementedException();
        }

        protected virtual string ConcreteOpenFile(FileInfo file)
        {
            throw new NotImplementedException();
        }

        protected virtual string GetExtension()
        {
            return "gz";
        }

        protected virtual StreamReader ConcreteGetStreamReader(FileInfo file)
        {
            return file.OpenText();
        }

        protected virtual StreamWriter ConcreteGetStreamWriter(FileInfo file, bool overwrite)
        {
            if (file.Exists && overwrite)
                return file.AppendText();
            return file.CreateText();
        }
        #endregion
    }
}
